package com.meida.module.system.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.meida.common.base.service.*;
import com.meida.common.constants.CommonConstants;
import com.meida.common.constants.QueueConstants;
import com.meida.common.enums.AuthStatusEnum;
import com.meida.common.enums.ColleconEnum;
import com.meida.common.enums.YesNoEnum;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.security.OpenHelper;
import com.meida.common.security.OpenUser;
import com.meida.common.utils.ApiAssert;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.module.system.client.entity.SysCompany;
import com.meida.module.system.client.entity.SysOrganization;
import com.meida.module.system.provider.mapper.SysCompanyMapper;
import com.meida.module.system.provider.service.SysAreaService;
import com.meida.module.system.provider.service.SysCompanyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 企业表 服务实现类
 *
 * @author flyme
 * @date 2019-06-02
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysCompanyServiceImpl extends BaseServiceImpl<SysCompanyMapper, SysCompany> implements SysCompanyService {
    @Resource
    private SysAreaService areaService;
    @Resource
    private BaseColleconService colleconService;

    @Autowired(required = false)
    private BaseAdminAccountService baseAdminAccountService;

    @Autowired(required = false)
    private BaseSysRoleService sysRoleService;

    @Autowired(required = false)
    private BaseProductService baseProductService;

    @Autowired(required = false)
    private BaseShopService baseShopService;

    @Autowired(required = false)
    private BaseAdminUserService baseAdminUserService;

    @Autowired(required = false)
    private BaseAppUserService baseAppUserService;

    @Autowired
    private SysCompanyMapper companyMapper;
    @Autowired
    private SysCompanyService companyService;


    @Override
    public void afterGet(CriteriaQuery cq, EntityMap result) {
        Long companyId = result.getLong("companyId");
        Integer colleconTag = colleconService.countCollecon(companyId, ColleconEnum.SC, SysCompany.class);
        result.put("colleconTag", colleconTag);
        String accountName = result.get("linkTel");
        EntityMap account = baseAdminAccountService.getAccount(accountName, "USERNAME");
        if (FlymeUtils.isNotEmpty(account)) {
            Long userId = account.getLong("userId");
            Long roleId = sysRoleService.getRoleId(userId);
            result.put("roleId", roleId);
        }
    }


    @Override
    public ResultBody beforeAdd(CriteriaSave cs, SysCompany company, EntityMap extra) {
        Long userId = OpenHelper.getUserId();
        company.setAuditState(AuthStatusEnum.AUTHING.getCode());
        String areaName = areaService.getAreaName(company.getProId(), company.getCityId(), company.getAreaId());
        Integer superAdmin = OpenHelper.getUser().getSuperAdmin();
        Long organizationId = company.getOrganizationId();
        if (CommonConstants.INT_0.equals(superAdmin)) {
            Long companyId = OpenHelper.getCompanyId();
            SysCompany currentCompany = companyService.getById(companyId);
            if (FlymeUtils.isNotEmpty(currentCompany)) {
                organizationId = currentCompany.getOrganizationId();
                company.setOrganizationId(organizationId);
            }
        }
        Boolean check = checkByCompanyName(organizationId, company.getCompanyName(), company.getBusinessLicNo());
        ApiAssert.isFalse("企业名称已存在", check);
        company.setAreaName(areaName);
        company.setManagerId(userId);
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterAdd(CriteriaSave cs, SysCompany company, EntityMap extra) {
        String shopName = cs.getParams("shopName");
        if (FlymeUtils.isNotEmpty(shopName)) {
            //如果有店铺信息则发送店铺注册通知
            try {
                OpenUser openUser = OpenHelper.getUser();
                Long companyId = company.getCompanyId();
                openUser.setCompanyId(companyId);
                cs.put("companyId", company.getCompanyId());
                amqpTemplate.convertAndSend(QueueConstants.QUEUE_SHOP_REG, cs);
                amqpTemplate.convertAndSend(QueueConstants.QUEUE_BIND_COMPANY, openUser);
            } catch (Exception e) {
                removeById(company.getCompanyId());
            }
        }
        return ResultBody.ok("申请成功");
    }

    /**
     * 企业审核
     *
     * @param map
     * @return
     */
    @Override
    public ResultBody setAuditState(Map map) {
        CriteriaUpdate<SysCompany> cu = new CriteriaUpdate(map, entityClass);
        SysCompany company = cu.getEntity(SysCompany.class);
        Long companyId = company.getCompanyId();
        ApiAssert.isNotEmpty("companyId不能为空", companyId);
        Integer auditState = company.getAuditState();
        String auditContent = auditState.equals(AuthStatusEnum.AUTHFAIL.getCode()) ? company.getAuditContent() : "已审核";
        cu.set("auditContent", auditContent);
        cu.set("auditState", auditState);
        ResultBody resultBody = baseUpdate(cu);
        if (resultBody.isOk()) {
            return ResultBody.ok("审核成功", auditState);
        } else {
            return ResultBody.failed("审核失败");
        }
    }

    @Override
    public ResultBody resetAuditState(Long companyId) {
        ApiAssert.isNotEmpty("主键不能为空", companyId);
        UpdateWrapper product = new UpdateWrapper();
        product.set("auditState", AuthStatusEnum.NOAUTH.getCode());
        product.set("auditContent", "");
        product.in("companyId", companyId);
        boolean result = update(product);
        return ResultBody.ok("", 0);

    }

    @Override
    public ResultBody getByAccount(String accountName) {
        List companyList = companyMapper.selectByAccount(accountName);
        return ResultBody.ok(companyList);
    }

    @Override
    public ResultBody getAuthCompanyList(Long userId, Long organizationId) {
        CriteriaQuery cq = new CriteriaQuery(SysCompany.class);
        cq.select(SysCompany.class, "companyId", "companyName");
        cq.eq(SysCompany.class, "auditState", 2);
        Integer superAdmin = OpenHelper.getUser().getSuperAdmin();
        //非超级管理员查询自己的企业
        if (CommonConstants.INT_0.equals(superAdmin)) {
            cq.eq(SysCompany.class, "organizationId", organizationId);
        }
        List<EntityMap> list = selectEntityMap(cq);
        List<Long> companyIds = companyMapper.selectUserCompanyIds(userId);
        EntityMap map = new EntityMap();
        map.put("companyList", list);
        map.put("companyIds", companyIds);
        return ResultBody.ok(map);
    }

    @Override
    public Boolean checkByCompanyName(String companyName, String businessLicNo) {
        QueryWrapper<SysCompany> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(SysCompany::getCompanyName, companyName).or().eq(FlymeUtils.isNotEmpty(businessLicNo), SysCompany::getBusinessLicNo, businessLicNo);
        int count = count(queryWrapper);
        return count > 0 ? true : false;
    }

    @Override
    public Boolean checkByCompanyName(Long organizationId, String companyName, String businessLicNo) {
        CriteriaQuery<SysCompany> queryWrapper = new CriteriaQuery(SysCompany.class);
        queryWrapper.eq(true, "organizationId", organizationId).and(e -> e.eq("companyName", companyName).or().eq(FlymeUtils.isNotEmpty(businessLicNo), "businessLicNo", businessLicNo));
        int count = count(queryWrapper);
        return count > 0 ? true : false;
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<EntityMap> listRecommend(CriteriaQuery cq, int count, boolean collecon, String companyType) {
        cq.select(SysCompany.class, "companyId", "companyName", "companyLogo");
        if (collecon) {
            setCollecon(cq);
        }
        cq.eq("auditState", AuthStatusEnum.AUTHSUCCESS.getCode());
        cq.eq("company.recommend", YesNoEnum.YES);
        cq.eq("companyType", companyType);
        cq.orderByDesc("company.createTime");
        if (count > 0) {
            cq.last("limit " + count);
        }
        return selectEntityMap(cq);
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<SysCompany> cq, SysCompany company, EntityMap requestMap) {
        cq.select(SysCompany.class, "companyId", "companyName", "companyLogo", "managerId", "areaName", "companyType", "companyAddress", "linkMan", "linkTel", "recommend", "auditState", "businessLicNo", "businessLic");
        cq.select(SysOrganization.class, "organizationName");
        setCollecon(cq);
        cq.likeByField(SysCompany.class, "companyName");
        cq.eq(SysCompany.class, "companyType");

        Integer superAdmin = OpenHelper.getUser().getSuperAdmin();
        if (CommonConstants.INT_1.equals(superAdmin)) {
            //如果是超级管理员
            cq.eq(SysCompany.class, "organizationId");
        } else {
            Long companyId = OpenHelper.getCompanyId();
            SysCompany currentCompany = companyService.getById(companyId);
            if (FlymeUtils.isNotEmpty(currentCompany)) {
                cq.eq(SysCompany.class, "organizationId", currentCompany.getOrganizationId());
            }

        }

        cq.eq(SysCompany.class, "auditState");
        cq.createJoin(SysOrganization.class);
        return ResultBody.ok();
    }

    @Override
    public ResultBody beforeListEntityMap(CriteriaQuery<SysCompany> cq, SysCompany company, EntityMap requestMap) {
        cq.eq(SysCompany.class, "organizationId");
        return super.beforeListEntityMap(cq, company, requestMap);
    }

    @Override
    public ResultBody beforeEdit(CriteriaUpdate<SysCompany> cu, SysCompany company, EntityMap extra) {
        if (FlymeUtils.isNotEmpty(company)) {
            String areaName = areaService.getAreaName(company.getProId(), company.getCityId(), company.getAreaId());
            company.setAreaName(areaName);
        }
        return ResultBody.ok();
    }


    @Override
    public ResultBody beforeDelete(CriteriaDelete<SysCompany> cd) {
        Long[] ids = cd.getIds();
        if (FlymeUtils.isNotEmpty(ids)) {
            for (Long id : ids) {
                SysCompany company = getById(id);
                if (company.getAuditState().equals(AuthStatusEnum.AUTHSUCCESS.getCode())) {
                    return ResultBody.failed("禁止删除已认证商家");
                }
                if (FlymeUtils.isNotEmpty(baseProductService)) {
                    int productCount = baseProductService.countByCompanyId(id);
                    if (productCount > 0) {
                        return ResultBody.failed("删除失败:企业已添加商品");
                    }
                }
            }
        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterDelete(CriteriaDelete cd, Long[] ids) {
        if (FlymeUtils.isNotEmpty(baseShopService) && FlymeUtils.isNotEmpty(ids)) {
            //删除企业店铺
            baseShopService.deletByCompanyIds(ids);
        }
        if (FlymeUtils.isNotEmpty(baseAdminUserService)) {
            baseAdminUserService.deleteByCompanyId(cd.getIdValue());
        }
        if (FlymeUtils.isNotEmpty(baseAppUserService)) {
            baseAppUserService.deleteByCompanyId(cd.getIdValue());
        }
        return super.afterDelete(cd, ids);
    }

    private void setCollecon(CriteriaQuery<SysCompany> cq) {
        //是否添加收藏标记
        Long userId = OpenHelper.getUserId();
        if (FlymeUtils.isNotEmpty(userId)) {
            cq.addSelect("(select count(targetId) from sys_collecon sc where sc.targetId=company.companyId and targetEntity='SysCompany' and userId=" + userId + ") colleconTag");
        }
    }
}
